import React, { forwardRef, useImperativeHandle } from "react";
import {
  Form,
  Input,
  Select,
  DatePicker,
  Radio,
  Checkbox,
  Upload,
  Button,
  FormInstance,
  FormItemProps,
  UploadProps,
  InputNumber,
  Modal,
} from "antd";
import { UploadOutlined } from "@ant-design/icons";
import {
  DynamicFormProps,
  DynamicFormRef,
  IFormItemConfig,
} from "@/types/public";
import Editor from "@/components/Editor";
import { loading } from "@/common/GlobalLoading";

const { TextArea } = Input;
const { RangePicker } = DatePicker;

const DynamicForm = forwardRef<DynamicFormRef, DynamicFormProps>(
  (
    {
      formItems,
      layout = "horizontal",
      onFinish,
      onFinishFailed,
      initialValues,
      submitButton,
    },
    ref
  ) => {
    const [form] = Form.useForm();
    // 暴露表单实例给外部
    useImperativeHandle(ref, () => ({
      form,
    }));
    const [editorValue, setEditorValue] = React.useState("");
    // 渲染不同类型的表单控件
    const renderFormItem = (item: IFormItemConfig, value: any) => {
      const {
        inputType,
        options,
        placeholder,
        size,
        title,
        disabled,
        uploadProps,
        key,
        style,
        className,
        multiple,
      } = item;

      switch (inputType) {
        case "input":
        case "hidden":
          return (
            <Input
              placeholder={placeholder}
              size={size}
              disabled={disabled}
              hidden={inputType == "hidden"}
            />
          );
        case "input-number":
          return (
            <InputNumber
              style={{ width: "100%" }}
              placeholder={placeholder}
              size={size}
              disabled={disabled}
            />
          );
        case "password":
          return (
            <Input.Password
              placeholder={placeholder}
              size={size}
              disabled={disabled}
            />
          );
        case "textarea":
          return (
            <TextArea
              placeholder={placeholder}
              rows={4}
              size={size}
              disabled={disabled}
            />
          );
        case "select":
          return (
            <Select
              placeholder={placeholder}
              mode={multiple ? "multiple" : undefined}
              size={size}
              disabled={disabled}
              options={options}
              style={style}
              filterOption={(input, option) => {
                return (option?.label ?? "")
                  .toLowerCase()
                  .includes(input.toLowerCase());
              }}
              className={className}
            />
          );
        case "date":
          return (
            <DatePicker
              placeholder={placeholder}
              size={size}
              disabled={disabled}
            />
          );
        case "editor":
          return (
            <Input
              placeholder={placeholder}
              size={size}
              disabled={disabled}
              suffix={
                <Button
                  color="cyan"
                  onClick={async () => {
                    let data = 0;
                    if (item.rawvalue && typeof item.rawvalue === "function") {
                      loading.open("获取原始数据");

                      let res = await item.rawvalue(form.getFieldsValue());
                      data = res.data.data.result;
                    }
                    loading.close();
                    Modal.info({
                      title: "编辑器内容",
                      width: "100%",
                      height: "100%",
                      style: {
                        top: 10,
                      },
                      footer: null,
                      closable: true,
                      content: (
                        <Editor
                          extendsJson={form.getFieldValue("extendsJson")}
                          recode={form.getFieldsValue()}
                          rawValue={data}
                          computedStr={form.getFieldValue(item.key)}
                          onSave={(e: string) => {
                            form.setFieldsValue({
                              [item.key]: e,
                            });
                          }}
                        />
                      ),
                    });
                  }}
                >
                  编辑
                </Button>
              }
            />
          );
        case "date-range":
          return <RangePicker size={size} disabled={disabled} />;
        case "radio":
          return (
            <Radio.Group size={size} disabled={disabled}>
              {options?.map((option) => (
                <Radio
                  key={option.value}
                  value={option.value}
                  disabled={option.disabled}
                >
                  {option.label}
                </Radio>
              ))}
            </Radio.Group>
          );
        case "checkbox":
          return (
            <Checkbox.Group disabled={disabled}>
              {options?.map((option) => (
                <Checkbox
                  key={option.value}
                  value={option.value}
                  disabled={option.disabled}
                >
                  {option.label}
                </Checkbox>
              ))}
            </Checkbox.Group>
          );
        case "upload":
          return (
            <Upload {...uploadProps} disabled={disabled}>
              <Button icon={<UploadOutlined />} disabled={disabled}>
                上传文件
              </Button>
            </Upload>
          );
        case "custom":
          return item.render ? item.render() : null;
        case "window":
          return (
            <Button
              color="cyan"
              onClick={async () => {
                Modal.info({
                  title: `《${title}》` + "编辑器内容",
                  icon: <></>,
                  width: "100%",
                  height: "100%",
                  style: {
                    top: 10,
                  },
                  footer: null,
                  closable: true,
                  content:
                    item.render &&
                    item.render(
                      form.getFieldValue(key),
                      form.getFieldsValue(),
                      key
                    ),
                });
              }}
            >
              编辑
            </Button>
          );
        default:
          return (
            <Input placeholder={placeholder} size={size} disabled={disabled} />
          );
      }
    };

    return (
      <Form
        form={form}
        layout={layout}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
        initialValues={initialValues}
        autoComplete="off"
      >
        {formItems.map((item) => {
          const { key, title, rules, dependencies, initialValue } = item;
          return (
            <Form.Item
              key={key}
              style={{ display: item.inputType == "hidden" ? "none" : "" }}
              name={key}
              label={title}
              rules={rules}
              dependencies={dependencies}
              initialValue={initialValue}
              // valuePropName={item.inputType === "upload" ? "fileList" : "value"}
              getValueFromEvent={
                item.inputType === "upload"
                  ? (e) => (Array.isArray(e || []) ? e : e?.fileList)
                  : undefined
              }
            >
              {renderFormItem(item, initialValue)}
            </Form.Item>
          );
        })}

        {submitButton && (
          <Form.Item>
            <Button type="primary" htmlType="submit">
              提交
            </Button>
          </Form.Item>
        )}
      </Form>
    );
  }
);

export default DynamicForm;
